import 'dart:ui';

import 'package:flutter/material.dart';
import 'dart:math' as math;
import 'package:vector_math/vector_math_64.dart' as vector;

import 'reset_test_matrix4/model/matrix4_data_model.dart';

class CanvasUtils {
  static Matrix4DataModel matrix4ToData(Matrix4 matrix4) {
    // 创建用于接收分解结果的变量
    vector.Vector3 translation = vector.Vector3.zero();
    vector.Quaternion rotation = vector.Quaternion.identity();
    vector.Vector3 scale = vector.Vector3.zero();

    // 分解矩阵
    matrix4.decompose(translation, rotation, scale);
    // 获取旋转角度
    double angle = math.atan2(matrix4.storage[1], matrix4.storage[0]);

    // 获取倾斜
    // 计算X轴到Y轴的倾斜
    final skewXtoY =
        math.atan2(matrix4.storage[4] / scale.y, matrix4.storage[0] / scale.x);
    // -  angle;
    // 计算Y轴到X轴的倾斜
    final skewYtoX =
        math.atan2(matrix4.storage[1] / scale.x, matrix4.storage[5] / scale.y);
    // - angle;

    // 将倾斜值转换为度
    // final skewXtoYDegrees = vector.degrees(skewXtoY);
    // final skewYtoXDegrees = vector.degrees(skewYtoX);

    // print("X轴到Y轴的倾斜角度:${skewXtoY}值, $skewXtoYDegrees 度");
    // print("Y轴到X轴的倾斜角度:${skewYtoX}值,$skewYtoXDegrees 度");

    vector.Vector3 position = matrix4.getTranslation();
    double scaleX = scale.x;
    double scaleY = scale.y;
    double skewX = skewXtoY;
    double skewY = skewYtoX;
    // 获取旋转角度
    // print("旋转角度（度）:${angle} ${angle * 180 / math.pi}");
    return Matrix4DataModel(
        dx: position.x,
        dy: position.y,
        scaleX: scaleX,
        scaleY: scaleY,
        rotationAngle: angle,
        skewX: skewX,
        skewY: skewY);
  }

  static Matrix4 dataToMatrix4(
    Matrix4DataModel data, {
    required Size imgSize,
  }) {
    Matrix4 scaleMatrix4 = Matrix4.identity()..scale(data.scaleX, data.scaleY);

    Matrix4 rotateMatrix4 = Matrix4.identity();
    rotateMatrix4
      ..translate(imgSize.width / 2, imgSize.height / 2) // 移动到中心
      ..rotateZ(data.rotationAngle)
      ..translate(-imgSize.width / 2, -imgSize.height / 2); // 移回原位

    Matrix4 skewMatrix4 = Matrix4.skew(data.skewX, data.skewY);

    Matrix4 translateMatrix4 = Matrix4.identity()..translate(data.dx, data.dy);
    return translateMatrix4 * rotateMatrix4 * scaleMatrix4 * skewMatrix4;
  }

// 获取变换后的四个顶点
  static List<Offset> getVertex(
      {required Size imgSize,
      required Matrix4 matrix,
      bool useCenterPoint = false}) {
    // 使用0，0原点旋转
    Offset originTopLeft = const Offset(0, 0);
    Offset originTopRight = Offset(imgSize.width, 0);
    Offset originBottomRight = Offset(
      imgSize.width,
      imgSize.height,
    );
    Offset originBottomLeft = Offset(0, imgSize.height);

    if (useCenterPoint) {
      // useCenterPoint 使用中心原点旋转，可以计算旋转后跟以原点绘制的矩形的旋转偏移量，从而计算旋转后左上角缩放固定不准的问题
      originTopLeft = Offset(-imgSize.width / 2, -imgSize.height / 2);
      originTopRight = Offset(imgSize.width / 2, -imgSize.height / 2);
      originBottomRight = Offset(
        imgSize.width / 2,
        imgSize.height / 2,
      );
      originBottomLeft = Offset(-imgSize.width / 2, imgSize.height / 2);
    }

    vector.Vector4 topLef = vector.Vector4(
        originTopLeft.dx, originTopLeft.dy, 0, 0); // 使用Vector3表示一个点;
    vector.Vector4 topRight = vector.Vector4(
        originTopRight.dx, originTopRight.dy, 0, 0); // 使用Vector3表示一个点;

    vector.Vector4 bottomRight = vector.Vector4(
        originBottomRight.dx, originBottomRight.dy, 0, 0); // 使用Vector3表示一个点;

    vector.Vector4 bottomLeft = vector.Vector4(
        originBottomLeft.dx, originBottomLeft.dy, 0, 0); // 使用Vector3表示一个点;

    vector.Vector4 topLeftPosition = matrix.transformed(topLef);
    vector.Vector4 topRightPosition = matrix.transformed(topRight);
    vector.Vector4 bottomRightPosition = matrix.transformed(bottomRight);
    vector.Vector4 bottomLeftPosition = matrix.transformed(bottomLeft);
    return [
      Offset(topLeftPosition.x, topLeftPosition.y),
      Offset(topRightPosition.x, topRightPosition.y),
      Offset(bottomRightPosition.x, bottomRightPosition.y),
      Offset(bottomLeftPosition.x, bottomLeftPosition.y),
    ];
  }

//计算矩形旋转后四个顶点的组成的宽高

// 计算两点之间的距离
  static double distance(Offset a, Offset b) {
    return math.sqrt(math.pow(b.dx - a.dx, 2) + math.pow(b.dy - a.dy, 2));
  }

// 计算矩形的宽度和高度
  static List<double> calculateWidthHeight(List<Offset> points) {
    // 确保传入的是四个顶点
    assert(points.length == 4);

    // 计算宽度（一个边长）
    double width = distance(points[0], points[1]);

    // 计算高度（相邻边长）
    double height = distance(points[1], points[2]);

    // print("Width: $width, Height: $height");
    return [width, height];
  }

  static drawResizeSvg(
      Canvas canvas, Picture picture, Size iconSize, Size originSize,
      {Color? color = Colors.white}) {
    Paint _paint = Paint();
    if (color != null) {
      _paint.colorFilter = ColorFilter.mode(color, BlendMode.srcIn);
    }
    canvas.saveLayer(
      null,
      _paint,
    );
    // canvas.translate(-size.width / 2, 0);
    canvas.scale(
        iconSize.width / originSize.width, iconSize.height / originSize.height);

    // 先定位好点，然后绘制
    canvas.drawPicture(picture);
    canvas.restore();
  }

  static drawGrid(Canvas canvas, Paint paint, Size size) {
    // 绘制四分之一的网格 ,要画全屏的画需要用镜像的方法
    //如果是相同或者对称的对象，可以通过缩放进行对称变化。
    // 沿x轴镜像，就相当于canvas.scale(1, -1)；
    // 沿y轴镜像，就相当于canvas.scale(-1, 1)；
    // 沿原点镜像，就相当于canvas.scale(-1, -1)；
    drawHalfGrid(canvas, paint, size);
  }

  static drawHalfGrid(Canvas canvas, Paint paint, Size size) {
    // 画网格
    double step = 20;
    paint
      ..color = Colors.grey
      ..strokeWidth = 1
      ..style = PaintingStyle.stroke;

    // 绘制横线
    canvas.save();
    // 计算绘制的 1/4 屏幕能画多少条线，然后循环就可以了
    for (int i = 0; i < size.height / step; i++) {
      canvas.drawLine(const Offset(0, 0), Offset(size.width, 0), paint);
      canvas.translate(0, step);
    }
    canvas.restore();
    // 绘制竖线
    canvas.save();
    // 计算绘制的 1/4 屏幕能画多少条线，然后循环就可以了
    for (int i = 0; i < size.width / step; i++) {
      canvas.drawLine(const Offset(0, 0), Offset(0, size.height), paint);
      canvas.translate(step, 0);
    }
    canvas.restore();
  }

  static drawCoor(Canvas canvas, Paint _paint, Size size) {
    _paint
      ..color = Colors.blue
      ..strokeWidth = 2;

    Offset yEndPoint = Offset(10, size.height);
    canvas.drawLine(Offset(10, 0), yEndPoint, _paint);
    canvas.drawLine(Offset(10, 0), Offset(0, 10), _paint);
    canvas.drawLine(Offset(10, 0), Offset(20, 10), _paint);
    // canvas.drawLine(yEndPoint, yEndPoint - Offset(10, -10), _paint);

    Offset xEndPoint = Offset(size.width, size.height - 40);
    canvas.drawLine(Offset(0, size.height - 40), xEndPoint, _paint);
    canvas.drawLine(xEndPoint, xEndPoint - Offset(10, 10), _paint);
    canvas.drawLine(xEndPoint, xEndPoint - Offset(10, -10), _paint);
  }

  static void drawText(
      {required Canvas canvas,
      required TextAlign textAlign,
      required Paint paint,
      Color? color,
      double fontSize = 14,
      FontWeight fontWeight = FontWeight.normal,
      Offset textOffset = Offset.zero,
      String text = ""}) {
    Paint textPaint = Paint()
      ..style = PaintingStyle.stroke
      ..strokeCap = StrokeCap.round
      ..strokeWidth = 1;
    TextPainter textPainter = TextPainter(
      text: TextSpan(
        text: text,
        style: TextStyle(
            color: color,
            fontSize: fontSize,
            fontWeight: fontWeight,
            foreground: color == null ? textPaint : null),
      ),
      textDirection: TextDirection.rtl,
    );
    textPainter.layout(); // 进行布局
    //获取size需要在layout之后
    Size textSize = textPainter.size;

    canvas.save();
    canvas.scale(1, -1);
    // 获取text的size尺寸，然后除于二
    if (textAlign == TextAlign.center) {
      textPainter.paint(canvas,
          Offset(-textSize.width / 2, -textSize.height / 2) + textOffset);
    } else if (textAlign == TextAlign.left) {
      textPainter.paint(
          canvas, Offset(-textSize.width, -textSize.height / 2) + textOffset);
    } else if (textAlign == TextAlign.start) {
      textPainter.paint(canvas, Offset(-textSize.width / 2, 0.0) + textOffset);
    }
    canvas.restore();
  }
}
